/// \file owl_parser.cpp.
///============================================================================\n
/// Name        : owl_parser.cpp\n
/// Author      : Gergely Lukacsy (info@dlog-reasoner.org)\n
/// Version     : 0.01\n
/// Copyright   : DERI\n
/// Description : OWL 2 XML parser, implementation file.\n
/// 
/// This file is part of the DParser and DLog 2 projects.\n
///============================================================================

using namespace xercesc;



// Constructor.
OWLPARSER::OWLPARSER(char* pFileName, bool bValidate, SROIQKB* pKB):
	nrUnknownElements(0){
	pFile = pFileName;
	this->bValidate = bValidate;
	pKnowledgeBase = pKB;
}

// Destructor.
OWLPARSER::~OWLPARSER() {
	ASSERT(mStack.empty());
}

DWORD OWLPARSER::getNrUnparsedElements() {
	return nrUnknownElements;
}

// Parse input ontology and set the hook to be called for each XML element.
void OWLPARSER::parseOWL() {

	// initialise the Xerces parser
    DBG("OWL Parser Initialisation");
    try {
       XMLPlatformUtils::Initialize();
     } catch (const XMLException& toCatch) {
           char* pMessage = XMLString::transcode(toCatch.getMessage());
           ERR("Error during initialization, exception message is: %s", pMessage);
           XMLString::release(&pMessage);
           abort();
       }

    // set properties of the SAX parser
    SAX2XMLReader* pSAXParser = XMLReaderFactory::createXMLReader();

	// set basic properties of the Xerces parser
	pSAXParser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
	pSAXParser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, false);
	

	// set validation features
	if (bValidate) {
		pSAXParser->setFeature(XMLUni::fgXercesSchema, true);
		pSAXParser->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
		pSAXParser->setFeature(XMLUni::fgXercesIdentityConstraintChecking, true);
		pSAXParser->setFeature(XMLUni::fgSAX2CoreValidation, true);
		pSAXParser->setFeature(XMLUni::fgXercesDynamic, true);
	} else {
		pSAXParser->setFeature(XMLUni::fgXercesSchema, false);
		pSAXParser->setFeature(XMLUni::fgXercesSchemaFullChecking, false);
		pSAXParser->setFeature(XMLUni::fgXercesIdentityConstraintChecking, false);
		pSAXParser->setFeature(XMLUni::fgSAX2CoreValidation, false);
		pSAXParser->setFeature(XMLUni::fgXercesDynamic, false);
	}

    // create SAX Handler
    OWLHANDLER* pDefaultHandler = new OWLHANDLER();
    pDefaultHandler->pOWLParser = this;
    pDefaultHandler->init();
    pSAXParser->setContentHandler(pDefaultHandler);
    pSAXParser->setErrorHandler(pDefaultHandler);

    // create a nasty (I know....) global varible to the knowledge base we will populate
    SINGLETON::pKB = pKnowledgeBase;

    // start parsing file
	DBG("Start parsing\n");

    try {
		ASSERT(pFile != NULL);
		pSAXParser->parse(pFile);
    } catch (const XMLException& toCatch) {
    	char* pMessage = XMLString::transcode(toCatch.getMessage());
        ERR("Exception message is: %s", pMessage);
        XMLString::release(&pMessage);
        abort();
    } catch (const SAXParseException& toCatch) {
        char* pMessage = XMLString::transcode(toCatch.getMessage());
        ERR("Exception message is: %s", pMessage);
        XMLString::release(&pMessage);
        abort();
    } catch (...) {
    	ERR("Unexpected Exception during Parsing");
        abort();
    }

    // close parsing
	DBG("Parsing finished\n");
	ASSERT(mStack.empty());

    delete pSAXParser;
    delete pDefaultHandler;
}

